/**
 * User: alesj
 * Date: 2004.8.23
 * Time: 15:18:18
 */

package com.generalynx.common.web.module;

import com.generalynx.common.userdata.IModuleUser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Iterator;
import java.util.LinkedList;

/**
 * Stored in request scope - encapsulates data about current module position.
 */
public class UserModules {

    protected final Log logger = LogFactory.getLog(getClass());

    private LinkedList m_path;
    private Module m_currentModule;
    private IModuleUser m_user;

    public UserModules(Module currentModule, IModuleUser user) throws SecurityException {
        if (!user.hasPermission(currentModule)) {
            throw new SecurityException("User " + user.getUsername() +
                                        " with insufficient permissions trying to access module "
                                        + currentModule.getName() + " (id = " +
                                        currentModule.getId() + ").");
        }
        m_user = user;
        m_path = new LinkedList();
        Module module = currentModule;
        while (module != null) {
            m_path.addFirst(module);
            module = module.getParent();
        }
        module = currentModule;
        while ((module = getPrimaryChild(module)) != null) {
            m_path.addLast(module);
        }
        m_currentModule = (Module)m_path.getLast();
    }

    private Module getPrimaryChild(Module module) {
        Iterator iter = module.getChildren().iterator();
        while (iter.hasNext()) {
            Module child = (Module)iter.next();
            if (isAllowed(child)) {
                return child;
            }
        }
        return null;
    }

    public UserModules(String currentModuleName, IModuleUser user) {
        this(Modules.getModule(currentModuleName), user);
    }

    public UserModules(int currentModuleId, IModuleUser user) {
        this(Modules.getModule(currentModuleId), user);
    }

    public Module getCurrentModule() {
        return m_currentModule;
    }

    /**
     * @param level the level in path of the selected module. 0 returns root.
     * @return currently selected module in path on level level
     */
    public Module getModule(int level) {
        try {
            return (Module)m_path.get(level);
        } catch (IndexOutOfBoundsException e) {
            throw new IndexOutOfBoundsException("No module on level " + level + " for this user");
        }
    }

    public boolean isAllowed(Module m) {
        return m_user.getModules().contains(m);
    }

}
